<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    /* 
    产生闭包的条件
        1. 函数嵌套
        2. 内部函数引用了外部函数的局部变量
        3. 调用外部
    什么时候创建? 
        执行内部函数定义, 也就是创建内部函数对象
    闭包是什么?
        是包含了被引用变量的一个容器(不是js对象), 被内部函数对象引用着
        fn2 ==> 内部函数对象 ==> 闭包
    如何使用闭包? / 如何让闭包在执行完函数后还能存活下来?
        返回内部函数, 在外部接收    最常用的手段
        用其它不会立即释放的变量引用内部函数对象  setTimeout(() => {})
    闭包的作用?
        延长局部变量的生命周期
        让函数外部能间接操作内部的局部变量
    区别闭包的三个操作
        产生闭包:  内部函数对象创建时产生, 包含那个被引用的变量的容器(不是js对象)
        使用闭包: 执行内部函数
        释放闭包: 让内部函数对象成为垃圾对象, 断开指向它的所有引用
    闭包的应用?
        具体功能说: 可以说根据id删除品牌(需要显示确定框)
        大的说: 我们定义的很多模块在编译后的代码中都存在闭包
    
    */

//    function fn1() {  // 进入fn1函数调用就产生闭包?
//         var a = 2;
//         function fn2 () {
//             a++;
//             console.log(a);
//             // console.log(fn2)
//         }

//         // var fn2 = function () {
//         //     a++;
//         //     console.log(a);
//         // }
//         return fn2  // 返回的是fn2的拷贝
//     }
//     var fn = fn1()
//     fn()
//     fn()

//     fn = null
    // 此时fn2是否还存在?  不存在  fn2只是指向内部函数对象的一个局部变量

    // 此时闭包是否还存在?
    // 为什么不存在了?

    /* 
    产生闭包?
    使用闭包?
    */


    // function showDedelay (time, msg) {
    //     var timoutId = setTimeout(() => {  // 内部必须有一个不会立即释放的变量保存函数
    //         alert(msg)
    //     }, time)
    // }
    // showDelay(1000, 'abc')  // 1s之后执行完回调函数, 回调函数会成功为垃圾对象, 闭也就会被回收

    // 题1
    
   /*  for ( var i = 0 ; i < 5; i++ ) {
        setTimeout(function(){
            console.log(i);
        }, 0);
    }  */
   
   // 55555

    // 题2
    
    /* for ( let i = 0 ; i < 5; i++ ) {
        setTimeout(function(){
            console.log(i);
        },0);
    } */
    // 01234 
   

    // 题3
    
    /* for ( var i = 0 ; i < 5; i++ ) {
        (function(j){
            setTimeout(function(){
                console.log(j);
            }, 0);
        })(i);
    }  */
    // 01234
   


    // 题4
    
    /* var scope = 'global scope'
    function checkscope(){
        var scope = 'local scope'
        return function f(){
            console.log(scope)
        }
    }
    var f = checkscope()
    console.log(f()) // local scope  / undfined
   */

   // 题5
   
  /*  var name = 'jerry'
    var obj = {  
        name : 'tom',  
        sayName(){ 
            console.log(this.name)  // tom
            return function(){  
                console.log(this.name);  // jerry
            }
        }   
    }
    obj.sayName()()  */

    // function fn (){}
    // fn()
    // window.fn()
  

    /* 
    两个数组，数组里是对象，遍历一个数组里的对象在另一个数组里有没有 
    没有的话把他push进去，有的话替换怎么做？
    */
  /*   const arr1 = [{id: 1, name: 'A'}, {id: 3, name: 'B'}]
    const arr2 = [{id: 3, name: 'C'}, {id: 5, name: 'D'}]

    arr1.forEach(item => {
        const index = arr2.findIndex(item2 => item2.id===item.id)
        if (index===-1) { // 没有找到
            arr2.push(item)
        } else {
            arr2[index] = item
            // arr2.splice(index, item, 1)
        }
    })
    console.log(arr2) */
    

  </script>
</body>
</html>